/* 
泛型接口
*/

 /* 
  1. 声明泛型类型: 在接口名的右侧  <T>   // T K V
  2. 使用泛型: 接口体中
  3. 指定泛型的具体类型: 定义实现时, 接口名的右侧 <具体类型>
  */

(() => {
  // 定义带泛型的接口
  interface BaseCRUD<T> {
    data: T[]; // 用来存储T类型对象的数组
    add (t: T): number   // 添加一个T类型的对象, 返回生成的id
    getById (id: number): T // 根据传入的id, 查找对应的T类型的对象
  }

  // 定义人的类
  class User {
    // 声明实例属性
    id?: number
    name: string
    age: number
    // 定义构造器初始化实例属性
    constructor (name, age) {
      this.name = name
      this.age = age
    }
  }

  // 定义操作User数据的CRUD类
  class UserCRUD implements BaseCRUD<User> {
    data: User[] = []  // 数组中只能保存User类型的实例

    // 添加用户返回用户的id
    add (user: User): number {
      // 生成一个唯一的id
      const id = Date.now()
      // 添加到user
      user.id = id
      // 保存到data中
      this.data.push(user)
      return id
    }
    
    // 根据id返回对应的user
    getById (id: number): User {
      return this.data.find(user => user.id===id)
    }
  }

  // 创建UserCRUD的实例
  const userCURD = new UserCRUD()
  // 添加user
  const id = userCURD.add(new User('Tom', 21))
  userCURD.add(new User('Jack', 22))
  // 读取所有user的数组
  console.log(userCURD.data)
  // 根据id获取对应的user
  console.log(userCURD.getById(id))
})()